﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using ComLib.ConfigService;
using ComLib.ComFun;
using System.Drawing;
using ComLib.ComType;
using System.IO;
using System.Reflection;

namespace IPCPages
{
    /// <summary>
    /// 对齐算法因子
    /// </summary>
    [XmlRootAttribute("AimingOption", Namespace = "UltrasonicSensor", IsNullable = false)]
    public class AimingOption : XmlSerializeBase
    {
        [XmlIgnore]
        public override string ConfigDirectory
        {
            get
            {
                string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
                directory = directory.Substring(6);
                return directory;
            }
        }

        public AimingOption()
        {

        }

        /// <summary>
        /// 镜头初始位置(cm), 相对于地面的初始高度
        /// </summary>
        private double _camHeight = 100;
        public double CamHeight
        {
            get { return _camHeight; }
            set { _camHeight = value; }
        }

        /// <summary>
        /// 点击移动的最长距离(cm)
        /// </summary>
        private double _maxMovingDistance = 70;
        public double MaxMovingDistance
        {
            get { return _maxMovingDistance; }
            set { _maxMovingDistance = value; }
        }

        /// <summary>
        /// 电机移动的总步数
        /// </summary>
        private int _totalStepsCount = 7200;
        public int TotalStepsCount
        {
            get { return _totalStepsCount; }
            set { _totalStepsCount = value; }
        }

        public double DistanceOfThousandStep
        {            
            get
            {
                double sv = _maxMovingDistance / TotalStepsCount * 1000.0D;
                return (double)Math.Round(sv, 9);
            }
        }

        /// <summary>
        /// 传感器的高度
        /// </summary>
        private double _sensorHeight = 225;
        public double SensorHeight
        {
            get { return _sensorHeight; }
            set { _sensorHeight = value; }
        }

        /// <summary>
        /// 眼睛到头顶的距离
        /// </summary>
        private double _eyesFormHeadtopHeight = 15;
        public double EyesFormHeadtopHeight
        {
            get { return _eyesFormHeadtopHeight; }
            set { _eyesFormHeadtopHeight = value; }
        }

        /// <summary>
        /// 对齐后的最大波动误差(电机移动步数)
        /// </summary>
        private int _maximumError = 100;
        public int MaximumError
        {
            get { return _maximumError; }
            set { _maximumError = value; }
        }

        /// <summary>
        /// 测量结果范围的置信区间
        /// </summary>
        private IntRangle _confidenceRangle = new IntRangle(50, 230);
        public IntRangle ConfidenceRangle
        {
            get { return _confidenceRangle; }
            set { _confidenceRangle = value; }
        }

        /// <summary>
        /// 最可信(可能)的身高区间
        /// </summary>
        private IntRangle _mostConfidentRangle = new IntRangle(150, 180);
        public IntRangle MostConfidentRangle
        {
            get { return _mostConfidentRangle; }
            set { _mostConfidentRangle = value; }
        }

        public override bool Serialize()
        {
            return Serializer.SaveToXml(ConfigFilePath, this);
        }
     
        public override bool Load()
        {
            AimingOption obj = (AimingOption)Serializer.LoadFromXml(ConfigFilePath, this.GetType());
            if (obj != null)
            {
                this._camHeight = obj._camHeight;
                this._eyesFormHeadtopHeight = obj._eyesFormHeadtopHeight;
                this._nVer = obj._nVer;
                this._maxMovingDistance = obj._maxMovingDistance;
                this._sensorHeight = obj._sensorHeight;
                this._totalStepsCount = obj._totalStepsCount;
                this._maximumError = obj._maximumError;
                this._confidenceRangle = obj._confidenceRangle;
                this._mostConfidentRangle = obj._mostConfidentRangle;
                return true;
            }
            else
            {
                ErrorMessage = Serializer.Message;
                return false;
            }
        }

        public override string ToString()
        {       
            StringBuilder builder = new StringBuilder("瞄准参数: ");
            FillFieldValueStringDelegate FillString =
              (string field, object val) =>
              {
                  builder.Append("[");
                  builder.Append(field);
                  builder.Append("]: ");
                  builder.Append(val.ToString() + "; ");
              };
            FillString("镜头初始高度:", _camHeight);
            FillString("电机运动最长距离:", _totalStepsCount);
            FillString("电机运动最大步数", _maxMovingDistance);
            FillString("电机运动每1000步的距离", DistanceOfThousandStep);
            FillString("测距传感器的高度", _sensorHeight);
            FillString("眼睛距离头顶的距离", _eyesFormHeadtopHeight);
            FillString("侧准后的最大波动误差", _maximumError);
            FillString("测量结果的置信区间", _confidenceRangle);
            FillString("测量结果的最可能区间", _mostConfidentRangle);
            return builder.ToString();
        }

        public IntRangle GetMostConfidentMeasuringRange()
        {
            IntRangle range = new IntRangle();
            int min = (int)(_sensorHeight - _mostConfidentRangle.Max);
            if (min < 0)
                min = 0;
            int max = (int)(_sensorHeight - _mostConfidentRangle.Min);
            if (max > _sensorHeight)
                max = (int)_sensorHeight;
            range.Min = min;
            range.Max = max;
            return range;
        }

        public IntRangle GetMaxMeasuringRange()
        {
            IntRangle range = new IntRangle();
            int min = (int)(_sensorHeight - _confidenceRangle.Max);
            if (min < 0)
                min = 0;
            int max = (int)(_sensorHeight - _confidenceRangle.Min);
            if (max > _sensorHeight)
                max = (int)_sensorHeight;
            range.Min = min;
            range.Max = max;
            return range;
        }
    }
}
